package aspectjutil.eventmanager;

import java.lang.reflect.Method;

/* Being instantiated for each class specified in @OnEvent annotation
 */
public class SubscriberMethodUnit {
	protected final Method method;
	protected final Class<?> methodClass;	// Should not be super class.
	protected final boolean amongInstancesInThread;
	public static final boolean DEFAULT_AMONG_INSTANCES_IN_THREAD_VALUE = true;
	protected final int turn;	// Specify order for execution
	public static final int DEFAULT_TURN_VALUE = 0;

	// Constructors -------------------------------------------------------------------------------
	public SubscriberMethodUnit( 
			Method method, Class<?> methodClass, boolean amongInstancesInThread, int turn) {
		this.method = method;
		this.methodClass = methodClass;
		this.amongInstancesInThread = amongInstancesInThread;
		this.turn = turn;
	}
	// --------------------------------------------------------------------------------------------
	
	// Getters ------------------------------------------------------------------------------------
	public final int getTurn() {
		return turn;
	}

	public final boolean isAmongInstancesInThread() {
		return amongInstancesInThread;
	}

	public final Method getMethod() {
		return method;
	}

	public final Class<?> getMethodClass() {
		return methodClass;
	}
	// --------------------------------------------------------------------------------------------

	// equals method and hashCode method ----------------------------------------------------------
	/* In order to avoid duplicate instance by multiple class loader:
	 * For equals method, make the following order:
	 * 		methodClass
	 * 		method
	 * 		For this class purpose (used for specific event), turn should not be considered.
	 * For hash method, use methodClass object and method object exclude turn object.
	 */
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((method == null) ? 0 : method.hashCode());
		result = prime * result
				+ ((methodClass == null) ? 0 : methodClass.hashCode());
		return result;
	}

	@Override
	public boolean equals( Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if ( getClass() != obj.getClass()) return false;
		
		SubscriberMethodUnit other = (SubscriberMethodUnit) obj;
		if (method == null) {
			if (other.method != null)
				return false;
		} 
		else if ( !method.equals( other.getMethod()))
			return false;
		if ( methodClass == null) {
			if ( other.methodClass != null)
				return false;
		} 
		else if ( !methodClass.equals( other.getMethodClass()))
			return false;
		return true;
	}
	// --------------------------------------------------------------------------------------------
	
}
